package com.example.lottery_system.dao.handler;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.AES;
import com.example.lottery_system.dao.DataObject.EncryptDO;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.charset.StandardCharsets;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * 这个是Java对象属性
 */
@MappedTypes(EncryptDO.class)
/**
 * 这个是需要转化后的 Mysql 的字段
 */
@MappedJdbcTypes(JdbcType.VARCHAR)
public class EncryptHandler extends BaseTypeHandler<EncryptDO> {

    Logger logger = LoggerFactory.getLogger(EncryptHandler.class);
    /**
     * 1， 设置密钥
     * @param ps 操作对象
     * @param i 索引
     * @param parameter Java传入的数据
     * @param jdbcType  数据库的类型
     * @throws SQLException
     */

    private byte[] Key = "12345678910qwsaz".getBytes(StandardCharsets.UTF_8);
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, EncryptDO parameter, JdbcType jdbcType) throws SQLException {
//        1. 校验一下
        if (ps == null || parameter.getPhone() == null) {
            logger.error("EncryptHandler:(setNonNullParameter)传入的数据错误!");
            return;
        }

        logger.info("原始电话号码为：" + parameter.getPhone());

//        2. 开始获取密码
        String encryptHex = encryptDate(parameter);

        // 3. 获取成功之后设置到数据库中
        ps.setString(i,encryptHex);
    }

    /**
     * 加密工作
     * @param parameter
     * @return
     */

    private String encryptDate( EncryptDO parameter) {
        AES aes = SecureUtil.aes(Key);
        String encryptHex = aes.encryptHex(parameter.getPhone());
        return encryptHex;
    }

    @Override
    public EncryptDO getNullableResult(ResultSet rs, String columnName) throws SQLException {
        /**
         * 1.获取密文
         */
        String cryptDate = rs.getObject(columnName).toString();
        logger.info("获取到的密文为；" + cryptDate);
        /**
         * 2. 解析密文
         */
        String decryptDate  = decryptDate(cryptDate);
        /**
         * 3. 打包返回
         */
        return new EncryptDO(decryptDate);
    }

    @Override
    public EncryptDO getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        /**
         * 1.获取密文
         */
        String cryptDate = rs.getObject(columnIndex).toString();
        logger.info("获取到的密文为；" + cryptDate);
        /**
         * 2. 解析密文
         */
        String decryptDate  = decryptDate(cryptDate);
        /**
         * 3. 打包返回
         */
        return new EncryptDO(decryptDate);
    }

    @Override
    public EncryptDO getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {


        /**
         * 1.获取密文
         */
        String cryptDate = cs.getObject(columnIndex).toString();
        logger.info("获取到的密文为；" + cryptDate);
        /**
         * 2. 解析密文
         */
        String decryptDate  = decryptDate(cryptDate);
        /**
         * 3. 打包返回
         */
        return new EncryptDO(decryptDate);
    }


    private String decryptDate(String cryptDate) {
//        1. 特判
        if (cryptDate == null) {
            logger.error("EncryptHandler中的密文为空!");
            return null;
        }

        // 2.获取aes对象
        AES aes = SecureUtil.aes(Key);

        // 3. 返回由 decryptStr 解密后的对象
        return aes.decryptStr(cryptDate);
    }
}
